package com.goldsprite.gameframeworks.simplephys.collis;

import com.badlogic.gdx.math.MathUtils;
import com.goldsprite.gameframeworks.simplephys.shape.PhysCircle;
import com.goldsprite.gameframeworks.simplephys.shape.PhysRect;
import com.goldsprite.gameframeworks.utils.math.Vector2;

public class CircleRectCollisionDetector implements CollisionDetector<PhysCircle, PhysRect> {
	private PhysRect tmpRect = new PhysRect();

	public boolean ccdCollision(Vector2 lastPos, PhysCircle currentA, PhysRect b, CollisionResult result) {
		if(CollisionUtils.isResetCalc) result.reset();

		float vx = currentA.x - lastPos.x;
		float vy = currentA.y - lastPos.y;

		if (vx == 0 && vy == 0) {
			return calculateCollision(currentA, b, result);
		}

		// 扩大矩形（各边外移圆的半径）
		float expandedLeft = b.x - currentA.radius;
		float expandedRight = b.x + b.width + currentA.radius;
		float expandedBottom = b.y - currentA.radius;
		float expandedTop = b.y + b.height + currentA.radius;

		float bestT = Float.POSITIVE_INFINITY;
		float bestNormalX = 0, bestNormalY = 0;

		// 计算圆形起始位置相对于扩大矩形的中心
		float expandedCenterX = (expandedLeft + expandedRight) * 0.5f;
		float expandedCenterY = (expandedBottom + expandedTop) * 0.5f;

		// 只检测离圆形起始点最近的两条边

		// 1. 检测最近的垂直边（左或右）
		if (vx != 0) {
			float targetX, normalX;
			if (lastPos.x < expandedCenterX) {
				// 圆形在左边，检测左边界
				targetX = expandedLeft;
				normalX = -1;
			} else {
				// 圆形在右边，检测右边界
				targetX = expandedRight;
				normalX = 1;
			}

			float t = (targetX - lastPos.x) / vx;
			if (t >= 0 && t <= 1 && t < bestT) {
				float intersectY = lastPos.y + t * vy;
				if (intersectY >= expandedBottom && intersectY <= expandedTop) {
					bestT = t;
					bestNormalX = normalX;
					bestNormalY = 0;
				}
			}
		}

		// 2. 检测最近的水平边（下或上）
		if (vy != 0) {
			float targetY, normalY;
			if (lastPos.y < expandedCenterY) {
				// 圆形在下边，检测下边界
				targetY = expandedBottom;
				normalY = -1;
			} else {
				// 圆形在上边，检测上边界
				targetY = expandedTop;
				normalY = 1;
			}

			float t = (targetY - lastPos.y) / vy;
			if (t >= 0 && t <= 1 && t < bestT) {
				float intersectX = lastPos.x + t * vx;
				if (intersectX >= expandedLeft && intersectX <= expandedRight) {
					bestT = t;
					bestNormalX = 0;
					bestNormalY = normalY;
				}
			}
		}

		if (bestT == Float.POSITIVE_INFINITY) {
			return false;
		}

		bestNormalX = Math.signum(-vx);
		bestNormalY = Math.signum(-vy);

		result.collided = true;
		result.normal.set(bestNormalX, bestNormalY);
		result.depth = (float)Math.sqrt(vx*vx + vy*vy) * (1 - bestT) + CollisionUtils.safeDistance;

		return true;
	}

	/**
	 * 圆形与矩形碰撞检测
	 */
	@Override
	public boolean calculateCollision(PhysCircle circle, PhysRect rect, CollisionResult result) {
		if(CollisionUtils.isResetCalc) result.reset();

		// 1. 找到矩形上距离圆心最近的点
		float closestX = MathUtils.clamp(circle.x, rect.x, rect.x + rect.width);
		float closestY = MathUtils.clamp(circle.y, rect.y, rect.y + rect.height);

		// 2. 计算最近点与圆心的距离
		float dx = closestX - circle.x;
		float dy = closestY - circle.y;
		float distanceSquared = dx * dx + dy * dy;

		// 3. 检查是否碰撞
		if (distanceSquared > circle.radius * circle.radius) {
			return false;
		}

		result.collided = true;

		// 4. 计算法线和深度
//		float collRadius = (float) Math.sqrt(distanceSquared);
		float collRadius = circle.radius;
		tmpRect.set(circle.x-collRadius, circle.y-collRadius, collRadius*2, collRadius*2);
		return CollisionUtils.calculateCollision(tmpRect, rect, result);

		//以下是不符合需求的精准法线信息: 效果会: 贴着物体表面圆弧型移动
//		// 正常碰撞
//		float distance = (float) Math.sqrt(distanceSquared);
//		result.normal.set(-dx / distance, -dy / distance);
//		result.depth = circle.radius - distance;
	}



	Vector2 tmpVec2 = new Vector2();
	Vector2 tmpVec22 = new Vector2();
	public boolean ccdCollision2(Vector2 moved, PhysCircle a, PhysRect b, CollisionResult result) {
//		if(CollisionUtils.isResetCalc) result.reset();
//
//		Vector2 aStart = tmpVec2.set(a.x, a.y).sub(moved);
//		Vector2 normal = tmpVec22.set(0);
//		boolean collided = false;
//		float depth = -1;
//
//		if (moved.x != 0) {
//			float targetX = moved.x > 0 ? b.x - a.radius : b.x + b.width;//朝右选择b左减a宽, 朝左选择b右, 然后aStart都用左即可
//			float t = (targetX - aStart.x) / moved.x;
//		}
//
//		return true;
		//这里暂时用矩形与矩形(暂时没时间写圆与矩形)
		tmpRect.set(a.x-a.radius, a.y-a.radius, a.radius*2, a.radius*2);
		return CollisionUtils.rectRectDetector.ccdCollision2(moved, tmpRect, b, result);
	}
}

